/*
 * ============================================================================
 *
 *       Filename:  main.c
 *
 *    Description:  
 *
 *        Version:  1.0
 *        Created:  02/03/20 19:31:12
 *       Revision:  none
 *       Compiler:  gcc
 *
 *         Author:  jianxi sun (jianxi), ycsunjane@gmail.com
 *   Organization:  
 *
 * ============================================================================
 */
 #define _GNU_SOURCE
#include <crypt.h>
#include <stdio.h>
#include <stdlib.h>
#include <pwd.h>
#include <shadow.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>

int main(int argc, char *argv[])
{
	if(argc != 3) {
		fprintf(stderr, "passchk username password\n");
		exit(-1);
	}

	char *username, *password;
	username = argv[1];
	password = argv[2];

	struct spwd *shadow_entry;
	char *p, *correct, *supplied, *salt;
	/* Read the correct hash from the shadow entry */
	shadow_entry = getspnam(username);
	if (shadow_entry == NULL) return 1;
	correct = shadow_entry->sp_pwdp;
	/* Extract the salt. Remember to free the memory. */
	salt = strdup(correct);
	if (salt == NULL) return 2;
	p = strchr(salt + 1, '$');
	if (p == NULL) return 2;
	p = strchr(p + 1, '$');
	if (p == NULL) return 2;
	p[1] = 0;
	/*Encrypt the supplied password with the salt and compare the results*/
	supplied = crypt(password, salt);
	if (supplied == NULL) return 2;
	return !!strcmp(supplied, correct);
}
